home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
newsgroups
/
misc.20000824-20010305
/
000158_news@columbia.edu _Fri Dec 29 12:42:36 2000.msg
< prev
next >
Wrap
Internet Message Format
|
2020-01-01
|
4KB
Return-Path: <news@columbia.edu>
Received: from watsun.cc.columbia.edu (watsun.cc.columbia.edu [128.59.39.2])
by monire.cc.columbia.edu (8.9.3/8.9.3) with ESMTP id MAA12269
for <kermit.misc@cpunix.cc.columbia.edu>; Fri, 29 Dec 2000 12:42:36 -0500 (EST)
Received: from newsmaster.cc.columbia.edu (newsmaster.cc.columbia.edu [128.59.59.30])
by watsun.cc.columbia.edu (8.8.5/8.8.5) with ESMTP id MAA19887
for <kermit.misc@watsun.cc.columbia.edu>; Fri, 29 Dec 2000 12:42:35 -0500 (EST)
Received: (from news@localhost)
by newsmaster.cc.columbia.edu (8.9.3/8.9.3) id MAA06772
for kermit.misc@watsun.cc.columbia.edu; Fri, 29 Dec 2000 12:31:26 -0500 (EST)
X-Authentication-Warning: newsmaster.cc.columbia.edu: news set sender to <news> using -f
From: Russ Allbery <rra@stanford.edu>
Subject: Re: Converting struct tm to time_t
Date: 29 Dec 2000 09:23:59 -0800
Organization: The Eyrie
Message-ID: <ylito3uonk.fsf@windlord.stanford.edu>
To: kermit.misc@columbia.edu
In comp.unix.programmer, Frank da Cruz <fdc@watsun.cc.columbia.edu> writes:
> If anybody has any helpful or simplifying suggestions, I'd be glad to
> hear them. The question is:
> How to convert a struct tm (which already is expressed in GMT) to
> a time_t which expresses the clock time in GMT (not local time) in
> a way that is reliable (works in any timezone and takes daylight
> savings into account) and is portable to as many UNIX platforms as
> possible (and how to do the same things on the platforms to which
> this portability does not extend)? The answer (as noted previously)
> is not mktime(), since it presumes its argument is in local time,
> not GMT.
> I'll copy this to comp.unix.programmer.
INN currently uses this, which seems to work fairly well. I'm the author
of this code; you can consider it to be in the public domain. Note that
this code requires that time_t be an arithmetic type, which may not work
properly on some non-UNIX platforms (it could presumably be replaced by a
long or something).
/* The number of days in each month. */
static const int MONTHDAYS[] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
/* Whether a given year is a leap year. */
#define ISLEAP(year) \
(((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0))
/*
** Given a struct tm representing a calendar time in UTC, convert it to
** seconds since epoch. Returns (time_t) -1 if the time is not
** convertable. Note that this function does not canonicalize the provided
** struct tm, nor does it allow out of range values or years before 1970.
*/
static time_t
mktime_utc(const struct tm *tm)
{
time_t result = 0;
int i;
/* We do allow some ill-formed dates, but we don't do anything special
with them and our callers really shouldn't pass them to us. Do
explicitly disallow the ones that would cause invalid array accesses
or other algorithm problems. */
if (tm->tm_mon < 0 || tm->tm_mon > 11 || tm->tm_year < 70)
return (time_t) -1;
/* Convert to a time_t. */
for (i = 1970; i < tm->tm_year + 1900; i++)
result += 365 + ISLEAP(i);
for (i = 0; i < tm->tm_mon; i++)
result += MONTHDAYS[i];
if (tm->tm_mon > 1 && ISLEAP(tm->tm_year + 1900))
result++;
result = 24 * (result + tm->tm_mday - 1) + tm->tm_hour;
result = 60 * result + tm->tm_min;
result = 60 * result + tm->tm_sec;
return result;
}
--
Russ Allbery (rra@stanford.edu) <http://www.eyrie.org/~eagle/>